home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / list / list.c
Encoding:
C/C++ Source or Header  |  1996-08-28  |  6.5 KB  |  352 lines

  1. /*
  2. ** Beginnings of a library module to support a list datatype in ACE (** INCOMPLETE **).
  3. ** Copyright (C) 1998 David Benn
  4. ** 
  5. ** This program is free software; you can redistribute it and/or
  6. ** modify it under the terms of the GNU General Public License
  7. ** as published by the Free Software Foundation; either version 2
  8. ** of the License, or (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. **
  19. ** NOTE: strlen() and strcpy() functions will have to be changed
  20. **       for use with ACE! (see ace:src/lib/c_string.c).
  21. **
  22. ** Author: David J Benn
  23. **   Date: 3rd,4th October 1995
  24. */
  25.  
  26. #include <exec/types.h>
  27. #include <exec/memory.h>
  28. #include <intuition/intuition.h>
  29.  
  30. #define pairtype    0
  31. #define shorttype    1
  32. #define longtype    2
  33. #define singletype    3
  34. #define stringtype    4
  35. #define notype        30
  36. #define marked        31
  37.  
  38. #define MEMTYPE        9L
  39.  
  40. #define OK        0L
  41. #define ERR        1L
  42.  
  43. #define FATAL        TRUE
  44. #define NONFATAL    FALSE
  45. #define ALLOCERR    1L
  46. #define INTUITIONERR    2L
  47.  
  48. typedef union value_type {
  49.     SHORT    shortnum;
  50.     LONG    longnum;
  51.     float    singlenum;
  52.     char    *string;
  53. } VALUE;
  54.  
  55. typedef struct atom_type {
  56.     ULONG kind;
  57.     VALUE value;
  58.     ULONG Reserved;    /* makes ATOM same size as PAIR */
  59. } ATOM;
  60.  
  61. typedef struct pair_type {
  62.     ULONG kind;
  63.     void *car;        /* points to: ATOM or PAIR */    
  64.     struct pair_type *cdr;    /* points to: PAIR */
  65. } PAIR;
  66.  
  67. /* Globals */
  68. struct Remember *AllocList = NULL;
  69. struct Library *IntuitionBase = NULL;
  70.  
  71. /* Prototypes */
  72. PAIR *reverse();
  73. void traverse();
  74.  
  75. void error();
  76. ATOM *atom();
  77. PAIR *cons();
  78. void *car();
  79. PAIR *cdr();
  80. void ShowAtom();
  81. ULONG TheFlags();
  82. ULONG alloc();
  83. void free_alloc();
  84. void startup();
  85. void cleanup();
  86.  
  87. /* Functions */
  88. void main()
  89. {
  90. PAIR *p;
  91. SHORT a,b,c;
  92.  
  93.     startup();
  94.  
  95.     /* Test of list functions */
  96.  
  97.     a = 3; 
  98.     b = 5; 
  99.     c = 9;
  100.  
  101.     p = cons(atom(&a,shorttype),
  102.         cons(atom(&b,shorttype),
  103.         cons(atom(&c,shorttype),NULL)));
  104.  
  105. /*    p = cons(cons(atom(&a,shorttype),NULL),
  106.              cons(atom("hello world",stringtype),NULL));
  107.  
  108.     ShowAtom(car(car(p)));
  109.     ShowAtom(car(cdr(p)));
  110. */
  111.  
  112.     p = reverse(p);
  113.     traverse(p);
  114.  
  115.     cleanup();
  116.     exit(OK);
  117. }
  118.  
  119. PAIR *reverse(L)
  120. PAIR *L;
  121. {
  122. /*
  123. ** Reverse a list of atoms by CONSing onto the natural recursion.
  124. */
  125.     if (L) return cons(atom(&((ATOM *)car(L))->value.shortnum,shorttype),
  126.                reverse(cdr(L)));
  127. }
  128.  
  129. void traverse(L)
  130. PAIR *L;
  131. {
  132. /*
  133.     if (L)
  134.     {
  135.         if (((PAIR *)car(L))->kind == pairtype) 
  136.         {
  137.             puts("--> car(L)");
  138.             traverse(car(L));
  139.         }
  140.         else
  141.         {
  142.             puts("--> show car(L)");
  143.             ShowAtom(car(L));
  144.         }
  145.  
  146.         puts("--> cdr(L)");
  147.         traverse(cdr(L));
  148.     }
  149. */
  150.     while (L)
  151.     {
  152.         ShowAtom(car(L));
  153.         L = cdr(L);    
  154.     }
  155.  
  156. }
  157.  
  158. void error(err, fatal)
  159. ULONG err, fatal;
  160. {
  161. /* 
  162. ** Display an error message and terminate program
  163. ** if error is fatal.
  164. */
  165.  
  166.     switch(err)
  167.     {
  168.         case ALLOCERR         : puts("Out of memory!"); 
  169.                       break;
  170.  
  171.         case INTUITIONERR     : puts("Can't open Intuition library");
  172.                       break;
  173.     }
  174.  
  175.     cleanup();
  176.     if (fatal) exit(ERR);
  177. }
  178.  
  179. ATOM *atom(value, type)
  180. void *value;
  181. ULONG type;
  182. {
  183. /*
  184. ** Create a new atom, record its type
  185. ** and return a pointer to the allocated
  186. ** object.
  187. */
  188. ATOM *a;
  189. char *s;
  190.  
  191.     a = (ATOM *)alloc(MEMTYPE, sizeof(ATOM));
  192.  
  193.     if (type == stringtype)
  194.     {
  195.         s = (char *)alloc(MEMTYPE, strlen((char *)value)+1);
  196.         if (s == NULL) error(ALLOCERR, FATAL);
  197.     }
  198.  
  199.     if (a == NULL)
  200.         error(ALLOCERR, FATAL);
  201.     else
  202.     {
  203.         a->kind = 1<<type;
  204.         
  205.         switch(type)
  206.         {
  207.           case shorttype  : a->value.shortnum = *((SHORT *)value); break;
  208.           case longtype      : a->value.longnum = *((LONG *)value); break;
  209.           case singletype : a->value.singlenum = *((float *)value); break;
  210.           case stringtype : strcpy(s,(char *)value); a->value.string = s; break;
  211.         }    
  212.     }
  213.  
  214.     return a;
  215. }
  216.  
  217. PAIR *cons(first, second)
  218. void *first;
  219. PAIR *second;
  220. {
  221. /*
  222. ** Constructs a pair and sets car and cdr links
  223. ** according to first and second parameters.
  224. ** While second must be a pair, the first may
  225. ** be either a pair or an atom.
  226. */ 
  227. PAIR *p;
  228.  
  229.     p = (PAIR *)alloc(MEMTYPE,sizeof(PAIR));
  230.  
  231.     if (p == NULL) 
  232.         error(ALLOCERR, FATAL);
  233.     else
  234.     {
  235.         p->kind = 1<<pairtype;
  236.         p->car = first;
  237.         p->cdr = second;
  238.     }
  239.  
  240.     return p;    
  241. }
  242.  
  243. void *car(pair)
  244. PAIR *pair;
  245. {
  246. /*
  247. ** Returns a pointer to the car link of a pair.
  248. ** May be a pointer to a pair or an atom.
  249. */
  250.  
  251.     if (pair == NULL) 
  252.         return NULL;    /* shouldn't happen */
  253.     else
  254.         return pair->car;
  255. }
  256.  
  257. PAIR *cdr(pair)
  258. PAIR *pair;
  259. {
  260. /*
  261. ** Returns a pointer to the cdr link of a pair.
  262. ** This pointer will always be to a pair.
  263. */
  264.     if (pair == NULL) 
  265.         return NULL;    /* signifies end of list */
  266.     else
  267.         return pair->cdr;
  268. }
  269.  
  270. void ShowAtom(a)
  271. ATOM *a;
  272. {
  273.     if (a == NULL)
  274.     {
  275.         puts("CAR is NULL!");
  276.     }
  277.     else 
  278.     if (a->kind == pairtype)
  279.     {
  280.         puts("CAR is a PAIR");
  281.     }
  282.     else
  283.     switch(a->kind)
  284.     {
  285.         case 1<<shorttype  : printf(" short: %d\n",((ATOM *)a)->value.shortnum);
  286.                      break;
  287.         case 1<<longtype   : printf("  long: %ld\n",((ATOM *)a)->value.longnum);
  288.                      break;
  289.         case 1<<singletype : printf("single: %lx\n",((ATOM *)a)->value.singlenum);
  290.                      break;
  291.         case 1<<stringtype : printf("string: %s\n",((ATOM *)a)->value.string);
  292.                      break;
  293.     }
  294. }
  295.  
  296. ULONG TheFlags(MemType,bytes)
  297. LONG MemType,bytes;
  298. {
  299. ULONG flags;
  300.  
  301.      switch(MemType)
  302.      {
  303.           case 0L : flags = MEMF_CHIP; break;
  304.           case 1L : flags = MEMF_FAST; break;
  305.           case 2L : flags = MEMF_PUBLIC; break;
  306.  
  307.           case 3L : flags = MEMF_CHIP | MEMF_CLEAR; break;
  308.           case 4L : flags = MEMF_FAST | MEMF_CLEAR; break;
  309.           case 5L : flags = MEMF_PUBLIC | MEMF_CLEAR; break;
  310.  
  311.         case 6L : flags = MEMF_ANY; break;
  312.         case 7L : flags = MEMF_ANY | MEMF_CLEAR; break;
  313.  
  314.         /* see basfun.c */
  315.         case 9L : flags = MEMF_ANY | MEMF_CLEAR; break;    
  316.  
  317.         /* if all else fails... */
  318.           default : flags = MEMF_ANY | MEMF_CLEAR; break;
  319.      }
  320.  
  321.     return flags;
  322. }
  323.  
  324. ULONG alloc(MemType,bytes)
  325. LONG MemType,bytes;
  326. {
  327. /* 
  328. ** Allocate memory as requested.
  329. */    
  330.      return((ULONG)AllocRemember(&AllocList,bytes,TheFlags(MemType,bytes)));     
  331. }
  332.  
  333. void free_alloc()
  334. {
  335. /* 
  336. ** Free all memory allocated by AllocRemember().
  337. */
  338.     if (AllocList != NULL) FreeRemember(&AllocList,TRUE);
  339. }
  340.  
  341. void startup()
  342. {
  343.     IntuitionBase = (struct Library *)OpenLibrary("intuition.library", 0L);
  344.     if (IntuitionBase == NULL) error(INTUITIONERR, FATAL);
  345. }
  346.  
  347. void cleanup()
  348. {
  349.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  350.     free_alloc();
  351. }
  352.